home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / SNIP0492.ARJ / DESCRYPT.C < prev    next >
C/C++ Source or Header  |  1991-10-01  |  10KB  |  401 lines

  1. /* descrypt.h - header for DES routines in descrypt.c                   */
  2. /* This file is public domain C source code written by Ross Cottrell.   */
  3.  
  4. /* The 64 chars of key/block represent 64 bits of data, 1 bit per byte. */
  5. /* Each byte is 0 or 1. Every 8th byte of key, from key[7], is ignored. */
  6. /* This gives us the famous 56 active bits for the key.                 */
  7.  
  8. void                        /* (re)initialise DES data for new key      */
  9. setkey( char    *key);      /* new key - an array of 64 chars           */
  10.  
  11. void                        /* encrypt/decrypt a block (64 chars)       */
  12. encrypt(char    *block,     /* array of 64 chars (to be replaced)       */
  13.         int     edflag);    /* flag: 0==encrypt, 1==decrypt (I think)   */
  14.  
  15. char *                      /* This hasn't much to do with DES as such. */
  16. crypt(  char    *pw,        /* It looks like a function used by unix    */
  17.         char    *salt);     /* for encrypting passwords using DES.      */
  18.  
  19.  
  20. /* @(#)descrypt.c   4.1 (Berkeley) 12/21/80 */
  21. /*
  22.  * This program implements the
  23.  * Proposed Federal Information Processing
  24.  *  Data Encryption Standard.
  25.  * See Federal Register, March 17, 1975 (40FR12134)
  26.  */
  27.  
  28. /*
  29.  * Initial permutation,
  30.  */
  31. static   char   IP[] = {
  32.    58,50,42,34,26,18,10, 2,
  33.    60,52,44,36,28,20,12, 4,
  34.    62,54,46,38,30,22,14, 6,
  35.    64,56,48,40,32,24,16, 8,
  36.    57,49,41,33,25,17, 9, 1,
  37.    59,51,43,35,27,19,11, 3,
  38.    61,53,45,37,29,21,13, 5,
  39.    63,55,47,39,31,23,15, 7,
  40. };
  41.  
  42. /*
  43.  * Final permutation, FP = IP^(-1)
  44.  */
  45. static   char   FP[] = {
  46.    40, 8,48,16,56,24,64,32,
  47.    39, 7,47,15,55,23,63,31,
  48.    38, 6,46,14,54,22,62,30,
  49.    37, 5,45,13,53,21,61,29,
  50.    36, 4,44,12,52,20,60,28,
  51.    35, 3,43,11,51,19,59,27,
  52.    34, 2,42,10,50,18,58,26,
  53.    33, 1,41, 9,49,17,57,25,
  54. };
  55.  
  56. /*
  57.  * Permuted-choice 1 from the key bits
  58.  * to yield C and D.
  59.  * Note that bits 8,16... are left out:
  60.  * They are intended for a parity check.
  61.  */
  62. static   char   PC1_C[] = {
  63.    57,49,41,33,25,17, 9,
  64.     1,58,50,42,34,26,18,
  65.    10, 2,59,51,43,35,27,
  66.    19,11, 3,60,52,44,36,
  67. };
  68.  
  69. static   char   PC1_D[] = {
  70.    63,55,47,39,31,23,15,
  71.     7,62,54,46,38,30,22,
  72.    14, 6,61,53,45,37,29,
  73.    21,13, 5,28,20,12, 4,
  74. };
  75.  
  76. /*
  77.  * Sequence of shifts used for the key schedule.
  78. */
  79. static   char   shifts[] = {
  80.    1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1,
  81. };
  82.  
  83. /*
  84.  * Permuted-choice 2, to pick out the bits from
  85.  * the CD array that generate the key schedule.
  86.  */
  87. static   char   PC2_C[] = {
  88.    14,17,11,24, 1, 5,
  89.     3,28,15, 6,21,10,
  90.    23,19,12, 4,26, 8,
  91.    16, 7,27,20,13, 2,
  92. };
  93.  
  94. static   char   PC2_D[] = {
  95.    41,52,31,37,47,55,
  96.    30,40,51,45,33,48,
  97.    44,49,39,56,34,53,
  98.    46,42,50,36,29,32,
  99. };
  100.  
  101. /*
  102.  * The C and D arrays used to calculate the key schedule.
  103.  */
  104.  
  105. static   char   C[28];
  106. static   char   D[28];
  107. /*
  108.  * The key schedule.
  109.  * Generated from the key.
  110.  */
  111. static   char   KS[16][48];
  112.  
  113. /*
  114.  * Set up the key schedule from the key.
  115.  */
  116.  
  117. setkey(key)
  118. char *key;
  119. {
  120.    register i, j, k;
  121.    int t;
  122.  
  123.    /*
  124.     * First, generate C and D by permuting
  125.     * the key.  The low order bit of each
  126.     * 8-bit char is not used, so C and D are only 28
  127.     * bits apiece.
  128.     */
  129.    for (i=0; i<28; i++) {
  130.       C[i] = key[PC1_C[i]-1];
  131.       D[i] = key[PC1_D[i]-1];
  132.    }
  133.    /*
  134.     * To generate Ki, rotate C and D according
  135.     * to schedule and pick up a permutation
  136.     * using PC2.
  137.     */
  138.    for (i=0; i<16; i++) {
  139.       /*
  140.        * rotate.
  141.        */
  142.       for (k=0; k<shifts[i]; k++) {
  143.          t = C[0];
  144.          for (j=0; j<28-1; j++)
  145.             C[j] = C[j+1];
  146.          C[27] = t;
  147.          t = D[0];
  148.          for (j=0; j<28-1; j++)
  149.             D[j] = D[j+1];
  150.          D[27] = t;
  151.       }
  152.       /*
  153.        * get Ki. Note C and D are concatenated.
  154.        */
  155.       for (j=0; j<24; j++) {
  156.          KS[i][j] = C[PC2_C[j]-1];
  157.          KS[i][j+24] = D[PC2_D[j]-28-1];
  158.       }
  159.    }
  160. }
  161.  
  162. /*
  163.  * The E bit-selection table.
  164.  */
  165. static   char   E[48];
  166. static   char   e[] = {
  167.    32, 1, 2, 3, 4, 5,
  168.     4, 5, 6, 7, 8, 9,
  169.     8, 9,10,11,12,13,
  170.    12,13,14,15,16,17,
  171.    16,17,18,19,20,21,
  172.    20,21,22,23,24,25,
  173.    24,25,26,27,28,29,
  174.    28,29,30,31,32, 1,
  175. };
  176.  
  177. /*
  178.  * The 8 selection functions.
  179.  * For some reason, they give a 0-origin
  180.  * index, unlike everything else.
  181.  */
  182. static   char   S[8][64] = {
  183.    14, 4,13, 1, 2,15,11, 8, 3,10, 6,12, 5, 9, 0, 7,
  184.     0,15, 7, 4,14, 2,13, 1,10, 6,12,11, 9, 5, 3, 8,
  185.     4, 1,14, 8,13, 6, 2,11,15,12, 9, 7, 3,10, 5, 0,
  186.    15,12, 8, 2, 4, 9, 1, 7, 5,11, 3,14,10, 0, 6,13,
  187.  
  188.    15, 1, 8,14, 6,11, 3, 4, 9, 7, 2,13,12, 0, 5,10,
  189.     3,13, 4, 7,15, 2, 8,14,12, 0, 1,10, 6, 9,11, 5,
  190.     0,14, 7,11,10, 4,13, 1, 5, 8,12, 6, 9, 3, 2,15,
  191.    13, 8,10, 1, 3,15, 4, 2,11, 6, 7,12, 0, 5,14, 9,
  192.  
  193.    10, 0, 9,14, 6, 3,15, 5, 1,13,12, 7,11, 4, 2, 8,
  194.    13, 7, 0, 9, 3, 4, 6,10, 2, 8, 5,14,12,11,15, 1,
  195.    13, 6, 4, 9, 8,15, 3, 0,11, 1, 2,12, 5,10,14, 7,
  196.     1,10,13, 0, 6, 9, 8, 7, 4,15,14, 3,11, 5, 2,12,
  197.  
  198.     7,13,14, 3, 0, 6, 9,10, 1, 2, 8, 5,11,12, 4,15,
  199.    13, 8,11, 5, 6,15, 0, 3, 4, 7, 2,12, 1,10,14, 9,
  200.    10, 6, 9, 0,12,11, 7,13,15, 1, 3,14, 5, 2, 8, 4,
  201.     3,15, 0, 6,10, 1,13, 8, 9, 4, 5,11,12, 7, 2,14,
  202.  
  203.     2,12, 4, 1, 7,10,11, 6, 8, 5, 3,15,13, 0,14, 9,
  204.    14,11, 2,12, 4, 7,13, 1, 5, 0,15,10, 3, 9, 8, 6,
  205.     4, 2, 1,11,10,13, 7, 8,15, 9,12, 5, 6, 3, 0,14,
  206.    11, 8,12, 7, 1,14, 2,13, 6,15, 0, 9,10, 4, 5, 3,
  207.  
  208.    12, 1,10,15, 9, 2, 6, 8, 0,13, 3, 4,14, 7, 5,11,
  209.    10,15, 4, 2, 7,12, 9, 5, 6, 1,13,14, 0,11, 3, 8,
  210.     9,14,15, 5, 2, 8,12, 3, 7, 0, 4,10, 1,13,11, 6,
  211.     4, 3, 2,12, 9, 5,15,10,11,14, 1, 7, 6, 0, 8,13,
  212.  
  213.     4,11, 2,14,15, 0, 8,13, 3,12, 9, 7, 5,10, 6, 1,
  214.    13, 0,11, 7, 4, 9, 1,10,14, 3, 5,12, 2,15, 8, 6,
  215.     1, 4,11,13,12, 3, 7,14,10,15, 6, 8, 0, 5, 9, 2,
  216.     6,11,13, 8, 1, 4,10, 7, 9, 5, 0,15,14, 2, 3,12,
  217.  
  218.    13, 2, 8, 4, 6,15,11, 1,10, 9, 3,14, 5, 0,12, 7,
  219.     1,15,13, 8,10, 3, 7, 4,12, 5, 6,11, 0,14, 9, 2,
  220.     7,11, 4, 1, 9,12,14, 2, 0, 6,10,13,15, 3, 5, 8,
  221.     2, 1,14, 7, 4,10, 8,13,15,12, 9, 0, 3, 5, 6,11,
  222. };
  223.  
  224. /*
  225.  * P is a permutation on the selected combination
  226.  * of the current L and key.
  227.  */
  228. static   char   P[] = {
  229.    16, 7,20,21,
  230.    29,12,28,17,
  231.     1,15,23,26,
  232.     5,18,31,10,
  233.     2, 8,24,14,
  234.    32,27, 3, 9,
  235.    19,13,30, 6,
  236.    22,11, 4,25,
  237. };
  238.  
  239. /*
  240.  * The current block, divided into 2 halves.
  241.  */
  242. static   char   L[32], R[32];
  243. static   char   tempL[32];
  244. static   char   f[32];
  245.  
  246. /*
  247.  * The combination of the key and the input, before selection.
  248.  */
  249. static   char   preS[48];
  250.  
  251. /*
  252.  * The payoff: encrypt a block.
  253.  */
  254.  
  255. encrypt(block, edflag)
  256. char *block;
  257. {
  258.    int i, ii;
  259.    register t, j, k;
  260.  
  261.    /*
  262.     * First, permute the bits in the input
  263.     */
  264.    for (j=0; j<64; j++)
  265.       L[j] = block[IP[j]-1];
  266.    /*
  267.     * Perform an encryption operation 16 times.
  268.     */
  269.    for (ii=0; ii<16; ii++) {
  270.       /*
  271.        * Set direction
  272.        */
  273.       if (edflag)
  274.          i = 15-ii;
  275.       else
  276.          i = ii;
  277.       /*
  278.        * Save the R array,
  279.        * which will be the new L.
  280.        */
  281.       for (j=0; j<32; j++)
  282.          tempL[j] = R[j];
  283.       /*
  284.        * Expand R to 48 bits using the E selector;
  285.        * exclusive-or with the current key bits.
  286.        */
  287.       for (j=0; j<48; j++)
  288.          preS[j] = R[E[j]-1] ^ KS[i][j];
  289.       /*
  290.        * The pre-select bits are now considered
  291.        * in 8 groups of 6 bits each.
  292.        * The 8 selection functions map these
  293.        * 6-bit quantities into 4-bit quantities
  294.        * and the results permuted
  295.        * to make an f(R, K).
  296.        * The indexing into the selection functions
  297.        * is peculiar; it could be simplified by
  298.        * rewriting the tables.
  299.        */
  300.       for (j=0; j<8; j++) {
  301.          t = 6*j;
  302.          k = S[j][(preS[t+0]<<5)+
  303.             (preS[t+1]<<3)+
  304.             (preS[t+2]<<2)+
  305.             (preS[t+3]<<1)+
  306.             (preS[t+4]<<0)+
  307.             (preS[t+5]<<4)];
  308.          t = 4*j;
  309.          f[t+0] = (k>>3)&01;
  310.          f[t+1] = (k>>2)&01;
  311.          f[t+2] = (k>>1)&01;
  312.          f[t+3] = (k>>0)&01;
  313.       }
  314.       /*
  315.        * The new R is L ^ f(R, K).
  316.        * The f here has to be permuted first, though.
  317.        */
  318.       for (j=0; j<32; j++)
  319.          R[j] = L[j] ^ f[P[j]-1];
  320.       /*
  321.        * Finally, the new L (the original R)
  322.        * is copied back.
  323.        */
  324.       for (j=0; j<32; j++)
  325.          L[j] = tempL[j];
  326.    }
  327.    /*
  328.     * The output L and R are reversed.
  329.     */
  330.    for (j=0; j<32; j++) {
  331.       t = L[j];
  332.       L[j] = R[j];
  333.       R[j] = t;
  334.    }
  335.    /*
  336.     * The final output
  337.     * gets the inverse permutation of the very original.
  338.     */
  339.    for (j=0; j<64; j++)
  340.       block[j] = L[FP[j]-1];
  341. }
  342.  
  343. char *
  344. crypt(pw,salt)
  345. char *pw;
  346. char *salt;
  347. {
  348.    register i, j, c;
  349.    int temp;
  350.    static char block[66], iobuf[16];
  351.    for(i=0; i<66; i++)
  352.       block[i] = 0;
  353.    for(i=0; (c= *pw) && i<64; pw++){
  354.       for(j=0; j<7; j++, i++)
  355.          block[i] = (c>>(6-j)) & 01;
  356.       i++;
  357.    }
  358.    
  359.    setkey(block);
  360.    
  361.    for(i=0; i<66; i++)
  362.       block[i] = 0;
  363.  
  364.    for(i=0;i<48;i++)
  365.       E[i] = e[i];
  366.  
  367.    for(i=0;i<2;i++){
  368.       c = *salt++;
  369.       iobuf[i] = c;
  370.       if(c>'Z') c -= 6;
  371.       if(c>'9') c -= 7;
  372.       c -= '.';
  373.       for(j=0;j<6;j++){
  374.          if((c>>j) & 01){
  375.             temp = E[6*i+j];
  376.             E[6*i+j] = E[6*i+j+24];
  377.             E[6*i+j+24] = temp;
  378.             }
  379.          }
  380.       }
  381.    
  382.    for(i=0; i<25; i++)
  383.       encrypt(block,0);
  384.    
  385.    for(i=0; i<11; i++){
  386.       c = 0;
  387.       for(j=0; j<6; j++){
  388.          c <<= 1;
  389.          c |= block[6*i+j];
  390.          }
  391.       c += '.';
  392.       if(c>'9') c += 7;
  393.       if(c>'Z') c += 6;
  394.       iobuf[i+2] = c;
  395.    }
  396.    iobuf[i+2] = 0;
  397.    if(iobuf[1]==0)
  398.       iobuf[1] = iobuf[0];
  399.    return(iobuf);
  400. }
  401.